using System.ComponentModel;

namespace Test.ConsoleProgram.Algorithm.Interview
{
    [TestDescriptionAttribute("面试题 0029. 顺时针打印矩阵")]
    public class No0029_SpiralOrder : AbsBaseTestItem
    {
        public override void OnTest()
        {
            Assert.TestExe(SpiralOrder,
                new int[][] {
                    new int[] { 1,2,3 },
                    new int[] { 4,5,6 },
                    new int[] { 7,8,9 },
                },
                new int[] { 1, 2, 3, 6, 9, 8, 7, 4, 5 });
            Assert.TestExe(SpiralOrder,
                new int[][] {
                    new int[] { 1,2,3,4 },
                    new int[] { 5,6,7,8 },
                    new int[] { 9,10,11,12 },
                },
                new int[] { 1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7 });
        }

        public int[] SpiralOrder(int[][] matrix)
        {
            if (matrix == null ||
                matrix.Length <= 0 ||
                matrix[0] == null ||
                matrix[0].Length <= 0)
            {
                return new int[0];
            }
            int rowsLen = matrix.Length;
            int columnLen = matrix[0].Length;

            int[] order = new int[rowsLen * columnLen];
            int index = 0;
            int left = 0, top = 0, right = columnLen - 1, bottom = rowsLen - 1;
            while (left <= right && top <= bottom)
            {
                for (int column = left; column <= right; column++)
                {
                    order[index++] = matrix[top][column];
                }
                for (int row = top + 1; row <= bottom; row++)
                {
                    order[index++] = matrix[row][right];
                }
                if (left < right && top < bottom)
                {
                    for (int column = right - 1; column >= left; column--)
                    {
                        order[index++] = matrix[bottom][column];
                    }
                    for (int row = bottom - 1; row > top; row--)
                    {
                        order[index++] = matrix[row][left];
                    }
                }
                left++;
                top++;
                right--;
                bottom--;
            }
            return order;
        }
    }
}
